#include "myfile.h"

_FILE* _fopen(const char* pathname, const char* flag) {
    int fd = -2; // 和系统接口调用出错时的情况分开
    if (strcmp("r", flag) == 0) {
        fd = open(pathname, O_RDONLY);
    }
    else if (strcmp("w", flag) == 0) {
        fd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0666);
    }
    else if (strcmp("a", flag) == 0) {
        fd = open(pathname, O_WRONLY | O_APPEND | O_CREAT, 0666);
    }
    if (fd == -1) {
        perror("open");
        return NULL;
    }
    if (fd == -2) {
        fprintf(stderr, "can't identify the flag\n");
        return NULL;
    }

    _FILE* fp = (_FILE*)malloc(sizeof(_FILE));
    if (NULL == fp) {
        perror("malloc");
        return NULL;
    }
    fp->fileno = fd;
    fp->flag = FLUSH_LINE;
    memset(fp->out_buffer, 0, 1024);
    fp->out_pos = 0;
    
    return fp;
}


int _fwrite(_FILE* fp, const char* s, int len) {
    memcpy(fp->out_buffer + fp->out_pos, s, len);
    int ret = len;
    fp->out_pos += len;

    if (fp->flag & FLUSH_NOW) {
        write(fp->fileno, fp->out_buffer, fp->out_pos);
        fp->out_pos = 0;
    }
    else if ((fp->flag & FLUSH_LINE) && fp->out_buffer[fp->out_pos - 1] == '\n') {
        write(fp->fileno, fp->out_buffer, fp->out_pos);
        fp->out_pos = 0;
    }
    else if ((fp->flag & FLUSH_ALL) && fp->out_pos == 1024) {
        write(fp->fileno, fp->out_buffer, fp->out_pos);
        fp->out_pos = 0;
    }

    return ret;
} 

void _fflush(_FILE* fp) {
    if (fp->out_pos > 0) {
        write(fp->fileno, fp->out_buffer, fp->out_pos);
        fp->out_pos = 0;
    }
}

void _fclose(_FILE* fp) {
    _fflush(fp);
    close(fp->fileno);
    fp->out_pos = 0;
    free(fp);
}
